package com.song.mall.auth.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.song.common.to.MemberTO;
import com.song.common.utils.HttpUtils;
import com.song.common.utils.R;
import com.song.mall.auth.feign.MemberFeignService;
import com.song.mall.auth.vo.SocialUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author 宋超
 * HP - the login name of the current user.
 * 2021/10/4 - the current system date.
 * 16:54 - the current system time.
 */
@Slf4j
@Controller
@RequestMapping("/web/oauth2")
public class OAuth2Controller {
    @Autowired
    private MemberFeignService memberFeignService;

    @GetMapping("/gitee/success")
    public String gitee(@RequestParam("code") String code, HttpSession session) throws Exception {
        // 准备请求参数
        Map<String, String> params = new HashMap<>();
        Map<String,String> query = new ConcurrentHashMap<>();
        Map<String,String> header = new ConcurrentHashMap<>();
        params.put("client_id", "0ffdfbb6fef92c351cc725b7b6d2f4e9054045ccaab5be628791dc0339c69630");
        params.put("redirect_uri", "http://auth.mall.com/web/oauth2/gitee/success");
        params.put("client_secret", "6eb3b538c6a1bcce528e236822e1e2216450548e4191b003634ff97c0260744f");
        params.put("code", code);
        params.put("grant_type", "authorization_code");

        // 获取accesstoken
        HttpResponse response = HttpUtils.doPost("https://gitee.com", "/oauth/token", "post", header, query, params);

        if(response.getStatusLine().getStatusCode()==200) {  //获取响应状态行以及响应状态码,并且是判断是否换取成功
            //如果是200，那么就获取到了access Tokenresponse = {$Proxy103@9999} "HTTP/1.1 200 OK [Date: Tue, 05 Oct 2021 07:48:26 GMT, Content-Type: application/json; charset=utf-8, Transfer-Encoding: chunked, Connection: keep-alive, Keep-Alive: timeout=60, Server: nginx, Vary: Accept-Encoding, X-XSS-Protection: 1; mode=block, X-Content-Type-Options: nosniff, X-UA-Compatible: chrome=1, Cache-Control: no-store, Pragma: no-cache, ETag: W/"94271679d4da8904c3c3cae7319901da", X-Request-Id: 17d3aac8ac944f9d9d216faa8448beed, X-Runtime: 0.081656, Vary: Origin, X-Frame-Options: SAMEORIGIN] org.apache.http.conn.BasicManagedEntity@79a710d3"
            String json = EntityUtils.toString(response.getEntity());//获取到响应体内容
            //System.out.println(json);
            //将响应体的内容转换成对应的对象
            //TODO 有bug 得不到uid
            SocialUser socialUser = JSON.parseObject(json, SocialUser.class);
            //拿到了access Token，并且还转换了响应的对象了，那么就是知道了当前是哪个社交用户登录成功
            //真正是不是登录成功，还得分一些情况
            // 1.如果当前用户如果是第一次进gulimall网站，就自动注册进来（为当前这个社交用户生成一个会员信息账号，以后这个社交账号就对应指定的会员）
            //使用社交账号对数据库的用户表进行关联
            //如果这个社交用户，从来没有注册过gulimall网站，就进行注册，如果注册了就查出这个用户的整个详细信息
            //远程调用用户服务，接收socialUser这个社交用户，以此来判断是登录还是自动注册这个社交用户，相当于用id关联上某个本系统的用户信息，

            R oauthlogin = memberFeignService.oauthlogin(socialUser);
            if (oauthlogin.getCode() == 0) { //说明是成功的
                //提取登陆成功后的用户信息
                MemberTO data = oauthlogin.getData("data", new TypeReference<MemberTO>() {
                });
                log.info("登录成功：用户信息: {}", data.toString());
                /**
                 * 第一次使用session，就命令浏览器保存相应的卡号，
                 * 以后浏览器访问哪个网站就会带上这个网站的cookie
                 * 子域之间：gulimall,auth.gulimall.com等
                 * 发卡的时候（指定域名为父域名），即使是子域系统发的卡，也能让父域直接使用
                 */
                //TODO 1.默认发的令牌。key是session,值是唯一字符串。但是作用域是当前域，那么当前域解决不了session共享的问题，解决子域session共享问题
                //TODO 2.使用JSON的序列化方式来序列化对象数据到redis中
                session.setAttribute("loginUser", data);
                //2.换取成功access Token，也即登录成功就跳到我们应用的首页
                return "redirect:http://mall.com";
            } else {
                return "redirect:http://auth.mall.com/login.html";
            }
        }
        return "redirect:http://auth.mall.com/login.html";
    }
}
